import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ConexaoBanco {
	
	private Connection con;
	private int idExecucao;
	
	public ConexaoBanco(){
		try{
			if (con == null){
				Class.forName("org.gjt.mm.mysql.Driver");
				con = DriverManager.getConnection("jdbc:mysql://localhost:3306/bpce", "root", "cristina");
			}
			else if (con.isClosed()){
				con = null;				
			}
		}
		catch(Exception e){
			e.printStackTrace();
		}		
	}

	public void addExecucao(int iteracoes) {
		Statement stm;
		ResultSet rs;
		
		try{
			stm = (Statement) con.createStatement();
			stm.execute("INSERT INTO EXECUCAO (DATA, NUM_ITERACOES) VALUES (NOW(), " + Integer.toString(iteracoes) + ")");
			
			rs = stm.executeQuery("SELECT MAX(ID) AS ID FROM EXECUCAO");
			rs.next();
			idExecucao = rs.getInt("ID");
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}

	public void addModelador(Modelador modelador) {
		Statement stm;
		String sql;
		
		try{
			stm = (Statement) con.createStatement();
			
			sql = "INSERT INTO MODELADOR (NOME, EXECUCAO_ID, QUALIDADE_INICIAL, ASSUNTO)" +
					"VALUES (" + modelador.getNomeModelador() + ", " + Integer.toString(this.idExecucao) + ", " + 
					          Integer.toString(modelador.getQualidade()) + ", '" + modelador.getEspecialidade() + "') ";
			
			stm.execute(sql);
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}

	public void incrementaKV(int idModelador, String assunto, int valor) {
		Statement stm;
		String sql;
		ResultSet rs;
		
		try{
			stm = (Statement) con.createStatement();
			sql = " SELECT VALOR " +
				  " FROM KV " +
				  " WHERE MODELADOR_ID = " + Integer.toString(idModelador) + 
				  " AND ASSUNTO = '" + assunto + "'";
			
			rs = stm.executeQuery(sql);
			
			if (rs.next()){
				int tmp = rs.getInt("VALOR");
				tmp += valor;
				
				sql = " UPDATE KV " +
					  " SET VALOR = " + Integer.toString(tmp) + 
					  " WHERE MODELADOR_ID = " + Integer.toString(idModelador) + 
					  " AND ASSUNTO = '" + assunto + "'";
			}
			else{
				sql = " INSERT INTO KV (MODELADOR_ID, ASSUNTO, VALOR) " +
						" VALUES (" + Integer.toString(idModelador) + ", '" + assunto + "', " + Integer.toString(valor) + ")";
			}
			
			stm.execute(sql);
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}

	public void addImportacaoDiagrama(Diagrama diagrama, double d) {
		Statement stm;
		String sql;
		int idDiagrama;
		float ptoVisualizacao;
		ResultSet rs;
		
		try{
			stm = (Statement) con.createStatement();
			
			sql = "SELECT ID, PTO_VISUALIZACAO " +
		  	  	  "FROM DIAGRAMA " +
		  	  	  "WHERE EXECUCAO_ID = " + Integer.toString(this.idExecucao) + " " +  
		  	  	  "AND MODELADOR_ID = " + getIdModelador(diagrama.getNomeModelador()) + " " + 
		  	  	  "AND NOME = '" + diagrama.getNomeDiagrama() + "'";
	
			rs = stm.executeQuery(sql);
			rs.next();
			idDiagrama = rs.getInt("ID");
			ptoVisualizacao = rs.getFloat("PTO_VISUALIZACAO");
			ptoVisualizacao += d;
			
			sql = "UPDATE DIAGRAMA " +
				  "SET QTDE_VEZES_IMPORTADO = QTDE_VEZES_IMPORTADO + 1," +
				  "	   PTO_VISUALIZACAO = " + Float.toString(ptoVisualizacao) + 	
				  "WHERE ID = " + Integer.toString(idDiagrama);
			
			stm.executeUpdate(sql);
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}
	
	private int getIdModelador(String nomeModelador){
		Statement stm;
		ResultSet rs;
		String sql;
		int idModelador;
		
		try{
			stm = (Statement) con.createStatement();
			
			sql = "SELECT ID " +
				  "FROM MODELADOR " +
				  "WHERE EXECUCAO_ID = " + Integer.toString(this.idExecucao) + " " +  
				  "AND NOME = " + nomeModelador;
			
			rs = stm.executeQuery(sql);
			rs.next();
			idModelador = rs.getInt("ID");
			return idModelador;
		}
		catch(Exception e){
			e.printStackTrace();
			return 0;
		}				
	}

	private void addAvaliacaoDiagrama(DiagramaAvaliado da, int idDiagramaPublicado) {
		Statement stm;
		String sql;
		ResultSet rs;
		int idDiagrama;
		float ptoAvaliacao;
		
		try{
			stm = (Statement) con.createStatement();
			
			sql = "SELECT ID, PTO_AVALIACAO " +
			  	  "FROM DIAGRAMA " +
			  	  "WHERE EXECUCAO_ID = " + Integer.toString(this.idExecucao) + " " +  
			  	  "AND MODELADOR_ID = " + getIdModelador(da.getNomeModelador()) + " " +  
			  	  "AND NOME = '" + da.getNomeDiagrama() + "'";
		
			rs = stm.executeQuery(sql);
			rs.next();
			idDiagrama = rs.getInt("ID");
			ptoAvaliacao = rs.getFloat("PTO_AVALIACAO");
			ptoAvaliacao += da.getPtoRecebido();

			sql = "INSERT INTO AVALIACAO_DIAGRAMA(DIAGRAMA_ID, NOTA, EXECUCAO_ID, DIAGRAMA_PUBLICADO_ID) " +
				  "VALUES (" + Integer.toString(idDiagrama) + ", " + Integer.toString(da.getNota()) + "," + Integer.toString(this.idExecucao) + ", " + Integer.toString(idDiagramaPublicado) + ")";
			
			stm.execute(sql);
			
			sql = "UPDATE DIAGRAMA " +
			  	  "SET PTO_AVALIACAO = " + Float.toString(ptoAvaliacao) +
			  	  "WHERE ID = " + Integer.toString(idDiagrama);
		
			stm.executeUpdate(sql);			
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}

	public void addDiagrama(Diagrama diagrama) {
		Statement stm;
		String sql;
		int idModelador, idDiagrama;
		ResultSet rs;
		
		try{
			stm = (Statement) con.createStatement();
			
			idModelador = getIdModelador(diagrama.getNomeModelador());
			
			sql = "INSERT INTO DIAGRAMA (NOME, MODELADOR_ID, PTO_INICIAL, EXECUCAO_ID, QTDE_DIAGRAMAS_IMPORTADOS, QUALIDADE, VERSAO, ASSUNTO) " +
				  "VALUES(" + diagrama.getNomeDiagrama() + ", " + Integer.toString(idModelador) + ", " + diagrama.getPtoInicial() + ", " + 
				  Integer.toString(this.idExecucao) + ", " + Integer.toString(diagrama.getQtdeDiagramasImportados()) + 
				  ", " + Integer.toString(diagrama.getFatorQualidade()) + ", " + Integer.toString(diagrama.getVersao()) + 
				  ",'" + diagrama.getAssunto() + "')";
			
			stm.execute(sql);
			
			if (diagrama.getListaDiagramaAvaliado() != null){
				rs = stm.executeQuery("SELECT MAX(ID) AS ID FROM DIAGRAMA");
				rs.next();
				idDiagrama = rs.getInt("ID");
				
				for(DiagramaAvaliado da:diagrama.getListaDiagramaAvaliado()){
					addAvaliacaoDiagrama(da, idDiagrama);
				}
			}
		}
		catch(Exception e){
			e.printStackTrace();
		}				
	}

	public float getUtilizacaoDiagrama(char c) {
		Statement stm, stt;
		String sql;
		ResultSet rs, rr;
		List<Integer> lista;
		int retorno;
		
		lista = new ArrayList<Integer>();
		lista.add(96367);
		
		retorno = 0;
		
		try{
			stm = (Statement) con.createStatement();
			stt = (Statement) con.createStatement();
			
			sql = "SELECT ID " +
		  	  "FROM DIAGRAMA " +
		  	  "WHERE EXECUCAO_ID = " + Integer.toString(112) + " " + 
		  	  "AND ID NOT IN (96367)";
			
			rs = stm.executeQuery(sql);
			
			while(rs.next()){
				Integer temp = new Integer(rs.getInt("ID"));
				
				sql = "SELECT DIAGRAMA_ID " +
			  	  "FROM AVALIACAO_DIAGRAMA " +
			  	  "WHERE EXECUCAO_ID = " + Integer.toString(112) + " " + 
			  	  "AND DIAGRAMA_PUBLICADO_ID = " + Integer.toString(temp);
				
				rr = stt.executeQuery(sql);
				
				while(rr.next()){
					Integer tmp = new Integer(rr.getInt("DIAGRAMA_ID"));
					
					if (lista.contains(tmp)){
						lista.add(temp);
						retorno++;
						break;
					}
				}
			}
		}
		catch(Exception e){
			e.printStackTrace();
		}
		
		return retorno;
	}
	
	public Map<Integer, Integer> calculaRanking(){
		Statement stm, stt;
		String sql;
		ResultSet rs, rr;
		int j;
		
		Map<Integer, Integer> mapaRetorno = new HashMap<Integer, Integer>();
		
		/*mapaRetorno.put(1,0);
		mapaRetorno.put(2,0);
		mapaRetorno.put(3,0);
		mapaRetorno.put(4,0);
		mapaRetorno.put(5,0);*/
		
		try{
			for (int i = 3400; i <= 3499; i++){
				stm = (Statement) con.createStatement();
				stt = (Statement) con.createStatement();
				
				sql = "SELECT D.ID, D.QUALIDADE, M.ASSUNTO " +
			  	  "FROM DIAGRAMA D, MODELADOR M " +
			  	  "WHERE D.EXECUCAO_ID = " + Integer.toString(i) + " " + 
			  	  "AND D.VERSAO = 10 " +
			  	  "AND D.MODELADOR_ID = M.ID " +
			  	  "ORDER BY (0.1 * PTO_INICIAL + 0.6 * PTO_AVALIACAO + 0.3 * PTO_VISUALIZACAO) DESC";
				
				rs = stm.executeQuery(sql);
				
				sql = "SELECT MAX(QUALIDADE) " +
			  	  "FROM DIAGRAMA " +
			  	  "WHERE EXECUCAO_ID = " + Integer.toString(i) + " " + 
			  	  "AND VERSAO = 10 ";
				
				rr = stt.executeQuery(sql);
				
				rr.next();
				Integer max = rr.getInt(1);
				
				j = 1;
				
				while(rs.next()){
					Integer tmp = rs.getInt("QUALIDADE");					
					if (tmp == max){
						Integer temp;
						if (mapaRetorno.containsKey(j)){
							temp = mapaRetorno.get(j);
						}
						else{
							temp = 0;
						}
						temp++;
						mapaRetorno.put(j, temp);
						
						if (j == 1){
							Integer lala;
							String assunto = rs.getString("ASSUNTO");
							if (assunto.equalsIgnoreCase("compra")){
								if (mapaRetorno.containsKey(-1)){
									lala = mapaRetorno.get(-1);
								}
								else{
									lala = 0;
								}
								
								lala++;
								mapaRetorno.put(-1, lala);
							}
						}
						
						break;
					}
					
					j++;
				}
			}
		}
		catch(Exception e){
			e.printStackTrace();
		}
		
		return mapaRetorno;
	}
}